import time
import qiniu
import hashlib
import zipfile

import requests
from datetime import datetime, timedelta
import os
from dotenv import load_dotenv

load_dotenv()


class WestCn:
    def __init__(self, username, ssl_api_pwd):
        #
        self.ssl_api_pwd = ssl_api_pwd
        self.username = username
        self.host = "https://api.west.cn"

    def get_token(self, time):
        """
        获取公共参数中的token
        参考接口文档：https://console-docs.apipost.cn/preview/4e5d940c9be19cda/73e3028374812fc5?target_id=9d27cd1e-6bfa-4665-9a8f-e421b7707a1c
        :param time: int类型，当前时间时间戳(秒),如：1689554756
        :return:  32位小写的md5值
        """
        text = f"{self.username}{self.ssl_api_pwd}{time}"
        return hashlib.md5(text.encode('utf-8')).hexdigest()

    def get_order_details(self, _domain):
        """
        获取订单详情
        参考接口文档：https://console-docs.apipost.cn/preview/4e5d940c9be19cda/73e3028374812fc5?target_id=2f3b0a20-aaf9-42ee-8ca3-b5a277c069be
        :param _domain: 域名
        :return: 返回请求的json结果
        """
        _t = int(time.time())
        _token = self.get_token(_t)
        url = f"{self.host}/newapi/ssl/info/detail?domain={_domain}&username={self.username}&time={_t}&token={_token}"
        print(url)
        r = requests.get(url)
        return r.json()

    def get_secret(self, _domain):
        """
        获取证书内容
        参考接口文档：https://console-docs.apipost.cn/preview/4e5d940c9be19cda/73e3028374812fc5?target_id=fae505a9-c375-4e17-a126-656d0b40ba07
        :param _domain: 域名
        :return: 返回证书的私钥和公钥字符串
        """
        _t = int(time.time())
        _token = self.get_token(_t)
        url = f"{self.host}/newapi/ssl/info/get-cert?type=PEM_Nginx&domain={_domain}&username={self.username}&time={_t}&token={_token}"
        print(url)
        r = requests.get(url)
        # 下载.zip文件到r，保存到本地
        r = requests.get(url)
        filename = f"{_domain}_{_t}.zip"
        with open(filename, "wb") as f:
            f.write(r.content)
            f.close()
            print("下载完成")
        # 解压.zip文件到cert目录，进入cert目录，并获取.key、.pem文件的内容
        _ca, _pri = "", ""
        with zipfile.ZipFile(filename, 'r') as zip_file:
            for file in zip_file.namelist():
                if file.endswith(".key"):
                    with zip_file.open(file) as f:
                        _pri = f.read().decode('utf-8')
                        f.close()
                if file.endswith(".pem"):
                    with zip_file.open(file) as f:
                        _ca = f.read().decode('utf-8')
                        f.close()
            zip_file.close()
            print("解压完成")
        return _ca, _pri


def check_ssl_expire(d):
    """
    参考文档：
    1.七牛云证书接口：https://developer.qiniu.com/fusion/8593/interface-related-certificate
    2.七牛云域名接口：https://developer.qiniu.com/fusion/4246/the-domain-name

    :param d:
    :return:
    """
    w = WestCn(os.getenv("WEST_CN_USERNAME"), os.getenv("WEST_CN_SSL_API_PWD"))
    _res = w.get_order_details(d)
    print("西部数码证书有效期-开始时间：", _res['data']['s_begin'])
    print("西部数码证书有效期-过期时间：", _res['data']['s_expire'])
    s_end = "执行结束"
    # 查询七牛云证书的有效期
    q_start, q_end = query_ssl_status(d)
    print(q_start, q_end)

    # 转换为 datetime 对象
    fmt = "%Y-%m-%d %H:%M:%S"
    begin = datetime.strptime(_res['data']['s_begin'], fmt)
    end = datetime.strptime(_res['data']['s_expire'], fmt)
    _begin = int(begin.timestamp())
    _end = int(end.timestamp())
    now = int(datetime.now().timestamp())

    # 判断西部数码的证书时间在有效期内
    if _begin < now < _end:
        print("西部数码的证书时间在有效期内")
    # 判断七牛云的证书时间在有效期内
    if q_start < now < q_end:
        print("七牛云的证书时间在有效期内")
    # 判断西部数码的证书时间和七牛的证书时间进行对比
    if _begin != q_start:
        print("西部数码的证书时间和七牛云不一致，需要替换为西部数码的证书")
        print("证书需要上传--开始执行上传")
        ca, pri = w.get_secret(d)
        access = os.getenv("QN_ACCESS_KEY")
        secret = os.getenv("QN_SECRET_KEY")
        q = qiniu.Auth(access, secret)

        domain = qiniu.DomainManager(q)
        result, response_info = domain.create_sslcert(f"{d}-{begin.strftime('%Y-%m-%d')}", d, pri, ca)
        print("证书需要上传--上传结果：")
        print(result, response_info)
        if response_info.status_code == 200:
            print("证书上传成功,证书ID：", result['certID'])
            # 调用域名绑定
            print("开始绑定域名")
            domain.put_httpsconf(d, result['certID'], False)
            print("绑定域名成功")

        else:
            print("证书上传失败")
    print("西部数码的证书和七牛云一致")
    exit(s_end)


def query_ssl_status(d):
    print("查询证书状态:", d)
    access = os.getenv("QN_ACCESS_KEY")
    secret = os.getenv("QN_SECRET_KEY")
    q = qiniu.Auth(access, secret)
    domain = qiniu.DomainManager(q)
    result, response_info = domain.get_domain(d)
    # print(result)
    if response_info.status_code == 200:
        print("证书ID：", result['https']['certId'])
        # 查询证书绑定状态
        url = '{0}/sslcert/{1}'.format(domain.server, result['https']['certId'])

        token = q.token_of_request(url)
        res = requests.get(url, headers={
            "Authorization": f"QBox {token}",
            "Content-Type": "application/x-www-form-urlencoded"
        }).json()
        _fmt = "%Y-%m-%d %H:%M:%S"
        print("七牛：证书有效期-开始时间：", datetime.fromtimestamp(res['cert']['not_before'] - 28800).strftime(_fmt))
        print("七牛：证书有效期-过期时间：", datetime.fromtimestamp(res['cert']['not_after'] - 28800).strftime(_fmt))
        return res['cert']['not_before'] - 28800, res['cert']['not_after'] - 28800
    else:
        print("查询失败")
        return 0, 0


if __name__ == '__main__':
    _d = os.getenv("DEFAULT_DOMAIN")
    check_ssl_expire(_d)
    pass
